import random
import copy
from collections import deque

from blessed import Terminal

term = Terminal()
UP = term.KEY_UP
RIGHT = term.KEY_RIGHT
LEFT = term.KEY_LEFT
DOWN = term.KEY_DOWN
direction = RIGHT

BORDER = '-'
BODY = '*'
HEAD = '#'
APPLE = 'x'
SPACE = ' '


snake = deque([[6, 5], [6, 4], [6, 3]])  # 蛇
food = [5, 10]

h, w = 10, 15
score = 0
speed = 3
MAX_SPEED = 6


def list_empty_spaces():
    """收集 world 二维数组中为空的元素到 list 中"""
    res = []
    for i in range(len(world)):  # 循环二维列表的高度 => [[1,2,3], [1,2, 3]]
        for j in range(len(world[i])):
            if world[i][j] == SPACE:
                res.append([i, j])
    return res


# with 上下文管理器
with term.cbreak(), term.hidden_cursor():

    # 清理屏幕
    print(term.home + term.clear)

    world = [[SPACE] * w for _ in range(h)]
    # 绘制竖线
    for i in range(h):
        world[i][0] = BORDER
        world[i][-1] = BORDER
    # 绘制横线
    for i in range(w):
        world[0][i] = BORDER
        world[-1][i] = BORDER

    for s in snake:
        world[s[0]][s[1]] = BODY
    head = snake[0]
    world[head[0]][head[1]] = HEAD
    world[food[0]][food[1]] = APPLE

    for row in world:
        print(' '.join(row))

    val = ''
    moving = False
    while val.lower() != 'q':  # quit
        # 阻塞
        val = term.inkey(timeout=1 / speed)  # ctrl+鼠标左键点击
        if val.code in [UP, DOWN, RIGHT, LEFT]:
            moving = True
        if not moving:
            continue

        # 按了上键 => up 并且 当前的方向不是向下，那么就可以向上移动
        # DOWN -> UP
        if val.code == UP and direction != DOWN:
            direction = UP
        if val.code == RIGHT and direction != LEFT:
            direction = RIGHT
        if val.code == LEFT and direction != RIGHT:
            direction = LEFT
        if val.code == DOWN and direction != UP:
            direction = DOWN

        # 移动蛇头
        head = copy.copy(snake[0])
        if direction == UP:
            head[0] -= 1  # Y 轴需要 - 1
        elif direction == RIGHT:
            head[1] += 1  # X 轴需要 +1
        elif direction == LEFT:
            head[1] -= 1
        elif direction == DOWN:
            head[0] += 1

        # 蛇头移动之后，所在位置原本的内容
        heading = world[head[0]][head[1]]
        ate_food = False
        if heading == APPLE:
            ate_food = True
            # 获得当前情况下空的元素
            empty_spaces = list_empty_spaces()
            # 随机获得其中一个空元素
            food = random.choice(empty_spaces)
            # 放置APPLE
            world[food[0]][food[1]] = APPLE
            speed = min(MAX_SPEED, speed * 1.07)
        elif heading == BORDER:
            # 撞到墙
            break
        elif heading == BODY and head != snake[-1]:
            # 蛇前进时，头会前进一格，尾部也会前进格
            # 环 => 蛇头 与 蛇尾连在一起时， head == snake[-1]
            break

        if not ate_food:
            # deque [1,2,3] => [0, 1,2,3] => [0,1,2]
            # 将尾部弹出
            tail = snake.pop()  # *
            # 将蛇尾变为空字符
            world[tail[0]][tail[1]] = SPACE

        snake.appendleft(head)

        # 重新绘制
        for s in snake:
            world[s[0]][s[1]] = BODY
        head = snake[0]
        world[head[0]][head[1]] = HEAD
        print(term.move_yx(0, 0))
        for row in world:
            print(' '.join(row))

        score = len(snake) - 3

        print(f'score: {score} - speed: {speed:.1f}')

print('game over')